using System;
using System.IO;
using System.Xml;
using Microsoft.BizTalk.ObjectModel;
using System.Diagnostics;
using System.Text;
using Microsoft.VS.Modeling.IMS;
using Microsoft.VS.Modeling.IMS.ObjViewer;
using System.Xml.Xsl;
using System.Collections.Generic;
using Microsoft.BizTalk.XLangS.Compiler.Interop;
namespace BTSProjectWizard.FileGenerators
{
	/// <summary>
	/// Summary description for StaticFileGenerator.
	/// </summary>
	public class ODXFileGenerator : IBTWizardFileGen
	{
		
		public void AddFile(string path,EnvDTE.Project proj,Wizard wiz,string suggestedName)
		{
		
			string newfile = null;
			newfile = Path.Combine(Path.GetDirectoryName(proj.FullName),Path.GetFileName(path));
            if (suggestedName != null)
                newfile = newfile.Replace(Path.GetFileNameWithoutExtension(newfile), suggestedName);
			try
			{

                XslCompiledTransform t = new XslCompiledTransform(false);
                t.Load(path);				
				object x = wiz.FindSymbol("dummyxml");
				string sxml="<s:doc xmlns:s='http://Schema1'></s:doc>";
				if(x!=null)
					sxml = x.ToString();
                StringReader ssr = new StringReader(sxml);
                XmlReader dummy = XmlReader.Create(ssr);
				MemoryStream stream = new MemoryStream();
				StreamWriter sw = new StreamWriter(stream);
				sw.WriteLine("#if __DESIGNER_DATA");
				sw.WriteLine("#error Do not define __DESIGNER_DATA.");
				sw.Flush();
				XsltArgumentList al = new XsltArgumentList();
                
				al.AddExtensionObject("http://wiz",wiz);
                XmlWriter writer = XmlWriter.Create(stream);
                t.Transform(dummy, al, stream);
				sw.WriteLine("\n#endif // __DESIGNER_DATA");
				sw.Flush();
				stream.Seek((long) 0, SeekOrigin.Begin);				
				StreamReader sr = new StreamReader(stream);
				MemoryStream xml = new MemoryStream();
				MemoryStream xsharp  = new MemoryStream();
                int num = Split(stream,xml,xsharp);
				xml.Seek((long) 0, SeekOrigin.Begin);
				Store store = new Store();
				store.LoadMetaModels(typeof(BizTalkModel).Assembly);
				BizTalkModel.CreateBizTalkModel(store, new Dummy(new Microsoft.BizTalk.TypeSystem.TypeTree(), 0));
				
				BizTalkModel model = store.GetSubStore(BizTalkModel.MetaModelGuid) as BizTalkModel;
				model.CodeRangeStore.HeaderOffset=num;
				CodeRangeStore crs  = model.CodeRangeStore;
				if (model != null)
				{
					model.SuspendNameValidation();
					model.SuspendRules();
                    
				}
				CodeRangeStore newStore = model.CodeRangeStore;
				Microsoft.VS.Modeling.IMS.Transaction xt = store.TransactionManager.BeginTransaction();
				try
				{
					IMSDebugXML.DeserializeStore(store, xml, newStore);
					xt.Commit();
				}
				finally
				{
					if(xt.IsActive)
						xt.Rollback();
				}

			
				using (Stream stream1 = File.Open(newfile, FileMode.Create))
				{
					Serializer.Save(store, stream1, false);
					stream1.Close();
				}
			}
			catch(Exception e)
			{
				Debug.WriteLine(e.ToString());
			}

			
			proj.ProjectItems.AddFromFile(newfile);
			
			
		}
		static int Split(Stream stream,Stream xmlStream,Stream xsharpStream)
		{
			int numlines = 0;
			stream.Seek((long) 0, SeekOrigin.Begin);
			xmlStream.Seek((long) 0, SeekOrigin.Begin);
			StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
			StreamWriter streamWriter = new StreamWriter(xmlStream, Encoding.UTF8);
			string theText = null;
			do
			{
				theText = streamReader.ReadLine();
				numlines++;

				if (theText == null)
				{
					System.Diagnostics.Debug.WriteLine("invalid odx file");
				}
			}
			while (theText != "#if __DESIGNER_DATA");
			theText = streamReader.ReadLine();
			numlines++;

			if (theText != "#error Do not define __DESIGNER_DATA.")
			{
				System.Diagnostics.Debug.WriteLine("invalid odx file");
			}
			do
			{
				theText = streamReader.ReadLine();
				

				if (theText == null)
				{
					System.Diagnostics.Debug.WriteLine("invalid odx file");
				}
				if (theText != "#endif // __DESIGNER_DATA")
				{
					streamWriter.WriteLine(theText);
				}
				numlines++;
				
			}
			while (theText != "#endif // __DESIGNER_DATA");
			streamWriter.Flush();
			xmlStream.Seek((long) 0, SeekOrigin.Begin);
			
			streamWriter = new StreamWriter(xsharpStream, Encoding.UTF8);
			
			do
			{
				streamWriter.WriteLine(streamReader.ReadLine());
			}while(streamReader.Peek() >= 0);
			streamWriter.Flush();
			xsharpStream.Seek((long) 0, SeekOrigin.Begin);
			return numlines;
		}

        #region IBTWizardFileGen Members

        public bool Init(XmlAttribute[] Attributes, Wizard wiz)
        {
            bool ret = true;
            //TODO:Something better here
            if (Attributes != null)
            {
                foreach (XmlAttribute a in Attributes)
                {
                    if (a.Name == "Condition")
                    {
                        //look for the value
                        object oc = wiz.FindSymbol(a.Value);
                        if (oc==null)
                        {
                            ret = false;
                        }
                    }
                }
            }
            return ret;
        }

        #endregion
    }
	public class Dummy : IBtsVsDocument
	{
		public Dummy(Microsoft.BizTalk.TypeSystem.TypeTree tt,uint field)
		{
			_tt = tt;
			_field = field;
		}
		Microsoft.BizTalk.TypeSystem.TypeTree _tt;
		uint _field;
		#region IBtsVsDocument Members
		
		public uint FileId
		{
			get
			{
				// TODO:  Add Dummy.FileId getter implementation
				return _field;
			}
		}

		public void PerformValidationActions()
		{
			// TODO:  Add Dummy.PerformValidationActions implementation
		}

		public ICodeSenseCompiler CodeSenseCompiler
		{
			get
			{
				// TODO:  Add Dummy.CodeSenseCompiler getter implementation
				return new CSCompiler();
			}
		}

		public Microsoft.BizTalk.TypeSystem.TypeTree TypeTree
		{
			get
			{
				// TODO:  Add Dummy.TypeTree getter implementation
				return _tt;
			}
		}

		#endregion

	}
    public class CSCompiler : ICodeSenseCompiler
    {
        #region ICodeSenseCompiler Members

        public void GetCodeSenseSym(BizTalkElement position, string expression, out Microsoft.BizTalk.XLangS.Compiler.Interop.TreeKind treeKind, out string name)
        {
            name = string.Empty;
            treeKind = Microsoft.BizTalk.XLangS.Compiler.Interop.TreeKind.eTreeNone;

        }

        public bool ValidateExpression(BizTalkElement position, string expression, out System.Collections.IList errorList)
        {
            List<string> foolist = new List<string>();
            errorList = foolist;
            return true;
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
           
        }

        #endregion
    }


		
	}

